<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-07-25 08:47:36
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!--缓存几何-->
<template>
	<div id="three_container"></div>
</template>

<script setup>
import * as THREE from "three";
import { AxesHelper } from "../case/helper/AxesHelper";
import { CameraHelper } from "../case/helper/CameraHelper";
import { WebGLRenderer } from "../create/renderer";
import { OrbitControlsHelper } from "../case/helper/OrbitControls";
import { PerspectiveCamera } from "../create/camera";
import { onMounted } from "vue";

//场景
const scene = new THREE.Scene();
AxesHelper(THREE, scene);
onMounted(() => {
	let container = document.getElementById("three_container");

	const camera = PerspectiveCamera(
		THREE,
		90,
		container.offsetWidth / container.offsetHeight,
		0.1,
		1000
	);
	camera.position.z = 200;
	camera.position.y = 200;
	CameraHelper(THREE, scene, camera);
	const renderer = WebGLRenderer(THREE, container);
	OrbitControlsHelper(THREE, scene, camera, renderer);

	const ambient = new THREE.AmbientLight({ color: 0xffffff });
	scene.add(ambient);
	Geometry();
	LineGeometry();
	TubeGeometry();
	function animate() {
		requestAnimationFrame(animate);
		renderer.render(scene, camera);
	}
	CurvePath();
	animate();
});
/**
 * 分组
 */
const Geometry = () => {
	const shape = new THREE.Shape();
	shape.moveTo(0, 0);
	shape.lineTo(100, 0);
	shape.lineTo(100, 100);
	const extrudeSettings = {
		depth: 10,
		bevelEnabled: false
	};
	const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
	const material = new THREE.MeshBasicMaterial({
		color: 0xff0000,
		mesh: true,
		wireframe: true
	});
	const mesh = new THREE.Mesh(geometry, material);
	scene.add(mesh);
};
/**
 * 线模型 line lineLoop lineSegments
 */
const LineGeometry = () => {
	const vertices = new Float32Array([
		0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 40
	]);
	const attribute = new THREE.BufferAttribute(vertices, 3);
	const geometry = new THREE.BufferGeometry();
	geometry.setAttribute("position", attribute);
	const lineMaterial = new THREE.LineBasicMaterial({ color: 0xff00ff });
	const lineMesh = new THREE.Line(geometry, lineMaterial);
	// scene.add(lineMesh);

	const lineLoopMesh = new THREE.LineLoop(geometry, lineMaterial);
	// scene.add(lineLoopMesh);

	const lineSegments = new THREE.LineSegments(geometry, lineMaterial);
	scene.add(lineSegments);
};
/**
 * 组合曲线CurvePath拼接曲线
 */
const CurvePath = () => {
	const R = 80;
	const arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, false);
	// 半圆弧的一个端点作为直线的一个端点
	var line1 = new THREE.LineCurve(
		new THREE.Vector2(R + 20, 200, 0),
		new THREE.Vector2(R + 20, 0, 0)
	);
	var line2 = new THREE.LineCurve(
		new THREE.Vector2(-R - 20, 0, 0),
		new THREE.Vector2(-R - 20, 200, 0)
	);
	const CurvePath = new THREE.CurvePath();
	CurvePath.curves.push(line1, arc, line2);

	const points = CurvePath.getPoints(200);
	const geometry = new THREE.BufferGeometry();
	geometry.setFromPoints(points);
	const material = new THREE.LineBasicMaterial({ color: 0xffffff });
	const line = new THREE.Line(geometry, material);
	scene.add(line);
	const geometry1 = new THREE.LatheGeometry(points, 30, 0, Math.PI);
	const material1 = new THREE.MeshBasicMaterial({ color: 0xffffff });
	const mesh = new THREE.Mesh(geometry1, material1);
	scene.add(mesh);
};
/**
 * 曲线路径管道TubeGeometry
 */
const TubeGeometry = () => {
	const path = new THREE.CatmullRomCurve3([
		new THREE.Vector3(-50, 20, 90),
		new THREE.Vector3(-10, 40, 40),
		new THREE.Vector3(0, 0, 0),
		new THREE.Vector3(60, -60, 0),
		new THREE.Vector3(70, 0, 80)
	]);
	// path:路径   40：沿着轨迹细分数  2：管道半径   25：管道截面圆细分数
	const geometry = new THREE.TubeGeometry(path, 40, 2, 5);
	const material = new THREE.MeshLambertMaterial({
		side: THREE.DoubleSide, //双面显示看到管道内壁
		wireframe: true
	});
	const mesh = new THREE.Mesh(geometry, material);
	scene.add(mesh);

	/**
	 * LineCurve3创建直线段路径
	 */

	const path1 = new THREE.LineCurve3(
		new THREE.Vector3(0, 100, 0),
		new THREE.Vector3(0, 0, 0)
	);
	// path:路径   40：沿着轨迹细分数  2：管道半径   25：管道截面圆细分数
	const geometry1 = new THREE.TubeGeometry(path1, 40, 2, 5);
	const mesh1 = new THREE.Mesh(geometry1, material);
	scene.add(mesh1);
	/**
	 *三维二次贝赛尔曲线
	 */
	// p1、p2、p3表示三个点坐标
	const p1 = new THREE.Vector3(-80, 0, 0);
	const p2 = new THREE.Vector3(20, 100, 0);
	const p3 = new THREE.Vector3(80, 0, 100);
	const path2 = new THREE.QuadraticBezierCurve3(p1, p2, p3);
	// path:路径   40：沿着轨迹细分数  2：管道半径   25：管道截面圆细分数
	const geometry2 = new THREE.TubeGeometry(path2, 40, 2, 5);
	const mesh2 = new THREE.Mesh(geometry2, material);
	scene.add(mesh2);

	/**
	 *
	 */
	// 创建多段线条的顶点数据
	const pp1 = new THREE.Vector3(0, 0, 100);
	const pp2 = new THREE.Vector3(0, 0, 30);
	const pp3 = new THREE.Vector3(0, 0, 0);
	const pp4 = new THREE.Vector3(30, 0, 0);
	const pp5 = new THREE.Vector3(100, 0, 0);
	// 1. 3D直线线段
	const line3 = new THREE.LineCurve3(pp1, pp2);
	// 2. 三维二次贝塞尔曲线
	const curve = new THREE.QuadraticBezierCurve3(pp2, pp3, pp4);
	// 3. 3D直线线段
	const line4 = new THREE.LineCurve3(pp4, pp5);

	const CurvePath = new THREE.CurvePath();
	// 三条线拼接为一条曲线
	CurvePath.curves.push(line3, curve, line4);

	// CurvePath:路径   40：沿着轨迹细分数  2：管道半径   25：管道截面圆细分数
	const geometry3 = new THREE.TubeGeometry(CurvePath, 50, 2, 25);
	const mesh3 = new THREE.Mesh(geometry3, material);
	scene.add(mesh3);

	/**
	 *
	 */
};
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
</style>
